#pragma once

#ifndef _H_ZQDB_H_
#define _H_ZQDB_H_

#include <zqdbase.h>

#if defined(__cplusplus)
extern "C" {
#endif//

#pragma pack(push, 1)

	//行情表结构
	//所有市场表 EXCHANGE = 市场列表[CODE,...]
	//具体市场表 CODE = 品种/板块列表[CODE,NAME,...]
	//具体品种/板块表 CODE.EXCHANGE = 代码静态和快照数据列表[CODE,NAME,...]
	//代码明细表 CODE.TICK = 明细数据列表[TICK,...]
	//代码K线表(M1、DAY) CODE.M1 = K线数据列表[...]
	//代码其他数据表 CODE.XXX = 其他数据列表[...]
#define STR_ZQDB_TABLE_EXCHANGE "EXCHANGE"

	//交易表结构
	//具体用户表 USER.MODULE = 用户列表[USERID,NAME,...]
	//具体持仓/委托/成交等表 XXX.MODULE = [XXX,...]
#define STR_ZQDB_TABLE_USER "USER"
#define STR_ZQDB_TABLE_INVESTOR "INVESTOR"
#define STR_ZQDB_TABLE_ACCOUNT "ACCOUNT"
#define STR_ZQDB_TABLE_POSITION "POSITION"
#define STR_ZQDB_TABLE_ORDER "ORDER"
#define STR_ZQDB_TABLE_TRADE "TRADE"


	//全局策略表,包含所有策略表信息
#define STR_ZQDB_TABLE_STRATEGY "STRATEGY"

	//全局产品表,包含所有自定义产品表信息（类似ETF、自定义投资组合）
#define STR_ZQDB_TABLE_PRODUCT "PRODUCT"

	//全局自选表,包含所有自选表信息
#define STR_ZQDB_TABLE_SELFSEL "SELFSEL"

#define INT64_TO_DOUBLE(x)		(double)((int64_t)(x))
#define UINT64_TO_DOUBLE(x)		(double)((usinged  int64_t)(x))

#define YYMMDD_TO_ULONG(y,m,d)		((y)*10000+m*100+d)
#define ULONG_TO_YYMMDD(x,y,m,d)	((y)=(x)/10000,(m)=(x)/100%100,(d)=(x)%100)

#define HHMMSS_TO_ULONG(h,m,s)		((h)*10000+m*100+s)
#define ULONG_TO_HHMMSS(x,h,m,s)	((h)=(x)/10000,(m)=(x)/100%100,(s)=(x)%100)

#define HHMMSSsss_TO_ULONG(h,m,s,sss)		(HHMMSS_TO_ULONG(h,m,s)*1000+(sss))
#define ULONG_TO_HHMMSSsss(x,h,m,s,sss)		((h)=(x)/(10000000),(m)=(x)/100000%100,(s)=(x)/1000%100,(sss)=(x)%1000)

#define MINUTE_TO_HHMM(x)		((x)/60*100 + (x)%60)
#define HHMM_TO_MINUTE(x)		((x)/100*60 + (x)%100)

#define SECOND_TO_HHMM(x)		MINUTE_TO_HHMM((x)/60)
#define HHMM_TO_SECOND(x)		(HHMM_TO_MINUTE(x)*60)

#define HHMMSS_TO_MINUTE(x)		HHMM_TO_MINUTE((x)/100)
#define HHMMSSsss_TO_MINUTE(x)	HHMMSS_TO_MINUTE((x)/1000)
#define MINUTE_TO_HHMMSS(x)		(MINUTE_TO_HHMM(x)*100)
#define MINUTE_TO_HHMMSSsss(x)	(MINUTE_TO_HHMMSS(x)*1000)

#define HHMMSS_TO_SECOND(x)		((x)/10000*60*60 + (x)%10000/100*60 + (x)%10000%100)
#define HHMMSSsss_TO_SECOND(x)	HHMMSS_TO_SECOND((x)/1000)
#define SECOND_TO_HHMMSS(x)		((x)/(60*60)*10000 + (x)%(60*60)/60*100 + (x)%60)
#define SECOND_TO_HHMMSSsss(x)	(SECOND_TO_HHMMSS(x)*1000)

	// # Chinese
#ifndef EXCHANGE_CFFEX
#define EXCHANGE_CFFEX "CFFEX"         //# China Financial Futures Exchange
#endif//
#ifndef EXCHANGE_SHFE
#define EXCHANGE_SHFE "SHFE"           //# Shanghai Futures Exchange
#endif//
#ifndef EXCHANGE_CZCE
#define EXCHANGE_CZCE "CZCE"           //# Zhengzhou Commodity Exchange
#endif//
#ifndef EXCHANGE_DCE
#define EXCHANGE_DCE "DCE"             //# Dalian Commodity Exchange
#endif//
#ifndef EXCHANGE_INE
#define EXCHANGE_INE "INE"             //# Shanghai International Energy Exchange
#endif//
#ifndef EXCHANGE_SSE
#define EXCHANGE_SSE "SSE"             //# Shanghai Stock Exchange
#endif//
#ifndef EXCHANGE_GFEX
#define EXCHANGE_GFEX "GFEX"             //# Guangzhou Futures Exchange
#endif//
#ifndef EXCHANGE_SZSE
#define EXCHANGE_SZSE "SZSE"           //# Shenzhen Stock Exchange
#endif//
#ifndef EXCHANGE_BSE
#define EXCHANGE_BSE "BSE"           //# Beijing Stock Exchange
#endif//
#ifndef EXCHANGE_HK
#define EXCHANGE_HK "HK"           //# Hongkong Stock Exchange
#endif//
	//#define EXCHANGE_SGE "SGE"             //# Shanghai Gold Exchange
	//#define EXCHANGE_WXE "WXE"             //# Wuxi Steel Exchange

	//     # Global
	//     SMART = "SMART"         # Smart Router for US stocks
	//     NYMEX = "NYMEX"         # New York Mercantile Exchange
	//     GLOBEX = "GLOBEX"       # Globex of CME
	//     IDEALPRO = "IDEALPRO"   # Forex ECN of Interactive Brokers
	//     CME = "CME"             # Chicago Mercantile Exchange
	//     ICE = "ICE"             # Intercontinental Exchange
	//     SEHK = "SEHK"           # Stock Exchange of Hong Kong
	//     HKFE = "HKFE"           # Hong Kong Futures Exchange
	//     SGX = "SGX"             # Singapore Global Exchange
	//     CBOT = "CBT"            # Chicago Board of Trade
	//     DME = "DME"             # Dubai Mercantile Exchange
	//     EUREX = "EUX"           # Eurex Exchange
	//     APEX = "APEX"           # Asia Pacific Exchange
	//     LME = "LME"             # London Metal Exchange
	//     BMD = "BMD"             # Bursa Malaysia Derivatives
	//     TOCOM = "TOCOM"         # Tokyo Commodity Exchange
	//     EUNX = "EUNX"           # Euronext Exchange

	//     # CryptoCurrency
	//     BITMEX = "BITMEX"
	//     OKEX = "OKEX"
	//     HUOBI = "HUOBI"
	//     BITFINEX = "BITFINEX"

	//产品类型
	///期货
#define PRODUCT_TYPE_Futures '1'
	///期货期权
#define PRODUCT_TYPE_Options '2'
	///组合
#define PRODUCT_TYPE_Combination '3'
	///即期
#define PRODUCT_TYPE_Spot '4'
	///期转现
#define PRODUCT_TYPE_EFP '5'
	///现货期权
#define PRODUCT_TYPE_SpotOption '6'
	///TAS合约
#define PRODUCT_TYPE_TAS '7'
	///指数
#define PRODUCT_TYPE_Index 'I'
	///股票
#define PRODUCT_TYPE_Stock 'E'
	///债券
#define PRODUCT_TYPE_Bond 'B'
	///基金
#define PRODUCT_TYPE_Fund 'D'
	///权证
#define PRODUCT_TYPE_Warrant 'W'
	///回购
#define PRODUCT_TYPE_Repo 'R'

	/////////////////////////////////////////////////////////////////////////
	///交易状态类型
	/////////////////////////////////////////////////////////////////////////
	///开盘前
#define XMT_Status_BeforeTrading '0'
	///非交易
#define XMT_Status_NoTrading '1'
	///连续交易
#define XMT_Status_Continous '2'
	///集合竞价报单
#define XMT_Status_AuctionOrdering '3'
	///集合竞价价格平衡
#define XMT_Status_AuctionBalance '4'
	///集合竞价撮合
#define XMT_Status_AuctionMatch '5'
	///收盘
#define XMT_Status_Closed '6'

	/////////////////////////////////////////////////////////////////////////
	///进入交易状态原因类型
	/////////////////////////////////////////////////////////////////////////
	///自动切换
#define XMT_Enter_Reason_Automatic '1'
	///手动切换
#define XMT_Enter_Reason_Manual '2'
	///熔断
#define XMT_Enter_Reason_Fuse '3'

	enum
	{
		MARKET_DATE_CHANGED = 0X0001,
		/*MARKET_NAMETABLE_CHANGED = 0X0002,
		MARKET_NAMETABLEATTACH_CHANGED = 0X0004,
		MARKET_STATICDATA_CHANGED = 0X0008,
		MARKET_DKPHDATA_CHANGED = 0X0010,*/

		MARKET_TIME_CHANGED = 0X0020,
		MARKET_PRICE_CHANGED = 0X0040,	//价变，量额不一定变
		MARKET_VOLUME_CHANGED = 0X0080,	//成交量变，成交额肯定变
		MARKET_AMOUNT_CHANGED = MARKET_VOLUME_CHANGED,
		MARKET_OTHER_CHANGED = 0X0100,

		MARKET_TICK_CHANGED = MARKET_VOLUME_CHANGED,
		MARKET_TREND_CHANGED = MARKET_PRICE_CHANGED | MARKET_VOLUME_CHANGED,
	};

	//周期定义

#ifndef USE_CYC_SEC
#define USE_CYC_SEC 0
#endif//USE_CYC_SEC

	enum PERIODTYPE
	{
		CYC_TICK = 0,
#if USE_CYC_SEC
		CYC_5SEC, //10秒基数的秒周期
		CYC_ANYSEC,
#endif//
		CYC_1MIN,
		CYC_5MIN,
		CYC_15MIN,
		CYC_30MIN,
		CYC_60MIN,
		CYC_ANYMIN,
		CYC_DAY,
		CYC_WEEK,
		CYC_MONTH,
		CYC_SEASON,
		CYC_YEAR,
		//CYC_ANYDAY,
		CYC_MAX,
	};

	//除权方式定义
	enum DWTYPE
	{
		DW_NONE = 0,	//不除权
		DW_BACKWARD,//向后	
		DW_FORWARD, //向前
		DW_MAX,
	};

	typedef struct tagWeightInfo
	{
		uint32_t Date;
		float PresentNumber;		// 每10股送股数，
		float MatchNumber;		// 每10股配股数，
		double MatchPrice;			// 配股价(元)，
		float Bonus;				// 每10股红利，
		float AddedNumber;		// 每10股增发股数
		int32_t SplitConsolidation;	// 拆并股，拆股为正(1→X时为X)；并股为负(Y→1时为-Y)，放大1000倍——港股专用
	} WEIGHT, *PWEIGHT;

	/**
	* @brief 常用周期定义
	*/
#define SECOND_OF_PERIOD_TICK		    0
#define SECOND_OF_PERIOD_1SEC		    1
#define SECOND_OF_PERIOD_5SEC		    5
#define SECOND_OF_PERIOD_1MIN		    60
#define SECOND_OF_PERIOD_5MIN		    60*5
#define SECOND_OF_PERIOD_15MIN		    60*15
#define SECOND_OF_PERIOD_30MIN		    60*30
#define SECOND_OF_PERIOD_HOUR		    60*60
#define SECOND_OF_PERIOD_4HOUR		    60*60*4
#define SECOND_OF_PERIOD_DAY		    60*60*24
#define SECOND_OF_PERIOD_WEEK		    60*60*24*7
#define SECOND_OF_PERIOD_MONTH		    60*60*24*30
#define SECOND_OF_PERIOD_SEASON		    60*60*24*90
#define SECOND_OF_PERIOD_YEAR		    60*60*24*365

	//User status.
#define USER_STATUS_OFFLINE '0' //离线
#define USER_STATUS_CONNECT '1' //连接中
#define USER_STATUS_CONNECTED '2' //已连接
#define USER_STATUS_LOGGED '3' //已登录

	//Direction of order/trade/position.
#define DIRECTION_LONG '0'
#define DIRECTION_SHORT '1'
#define DIRECTION_NET '2'

	//Offset of order/trade.
#define OFFSET_OPEN '0'
#define OFFSET_CLOSE '1'
#define OFFSET_CLOSETODAY '2'
#define OFFSET_CLOSEYESTERDAY '3'

	//Order status.
#define ORDER_STATUS_SUBMITTING '0'
#define ORDER_STATUS_NOTTRADED '1'
#define ORDER_STATUS_PARTTRADED '2'
#define ORDER_STATUS_ALLTRADED '3'
#define ORDER_STATUS_CANCELLED '4'
#define ORDER_STATUS_REJECTED '5'

	//Order type.
#define ORDER_LIMIT '0' //限价单
#define ORDER_MARKET '1' //市价单
#define ORDER_FAK '2' //立即成交剩余指令自动撤销指令(FAK指令)，指在限定价位下达指令，如果该指令下部分申报手数成交，该指令下剩余申报手数自动被系统撤销。
#define ORDER_FOK '3' //立即全部成交否则自动撤销指令(FOK指令)，指在限定价位下达指令，如果该指令下所有申报手数未能全部成交，该指令下所有申报手数自动被系统撤销。如果交易所不支持FOK，则改成剩余转限价
//#define ORDER_STOP '4' //stop order是对市场不可见的，只有当市场价格到了设定的价格(stop price)，订单才会被推向市场

	//Option type.
#define OPTION_CALL '0'
#define OPTION_PUT '1'

	//Currency.
#define CURRENCY_USD '0'
#define CURRENCY_HKD '1'
#define CURRENCY_CNY '2'

	typedef struct tagTradeTimeInfo
	{
		uint8_t PreTradeTime;
		uint8_t TradeTimeCount;
		uint16_t TradeTime[4][2];
	}TRADETIMEINFO, *PTRADETIMEINFO;

	typedef struct tagExchangeInfo
	{
		char Exchange[MAX_EXCHANGE_LENGTH + 1];
		char Name[MAX_NAME_LENGTH + 1];
		union
		{
			TRADETIMEINFO TradeTimeInfo;
			struct
			{
				uint8_t PreTradeTime; // 盘前交易时间（集合竞价）
				uint8_t TradeTimeCount; // 交易时段数量
				uint16_t TradeTime[4][2]; // 交易时段描述[最多只是4个交易时段，每个时段包括开始、结束时间，精确到分，HH * 60 + MM格式]
			};
		};
		uint8_t TradeTimeZone; // 该市场所处时区
		uint32_t TradeDay; // 当前交易日期[YYYYMMDD格式]
						   //uint32_t Date; // 市场日期[YYYYMMDD格式]
						   //uint32_t Time; // 市场时间[HHMMSS格式]
		int32_t DiffSecs; // 本地时差秒数
						  //char Status[4]; // 市场状态，最多3级状态，Status[0]是业务状态，Status[1-3]是连接状态
		char Status; //市场状态
		char EnterReason; // 进入状态原因
	}EXCHANGEINFO, *PEXCHANGEINFO;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, NAME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, PRE_TRADE_TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_COUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_FROM1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_TO1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_FROM2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_TO2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_FROM3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_TO3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_FROM4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_TO4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_TIME_ZONE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TRADE_DATE);
	//DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, DATE);
	//DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, DIFF_SECS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, STATUS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, EXCHANGE, ENTER_REASON);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, EXCHANGE, 17);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, EXCHANGE);

	typedef struct tagProductInfo
	{
		char Exchange[MAX_EXCHANGE_LENGTH + 1];
		char Product[MAX_PRODUCT_LENGTH + 1];
		char Name[MAX_NAME_LENGTH + 1];
		char Type; //类型
		union
		{
			TRADETIMEINFO TradeTimeInfo;
			struct
			{
				uint8_t PreTradeTime; // 盘前交易时间（集合竞价）
				uint8_t TradeTimeCount; // 交易时段数量
				uint16_t TradeTime[4][2]; // 交易时段描述[最多只是4个交易时段，每个时段包括开始、结束时间，精确到分，HH * 60 + MM格式]
			};
		}; 
		char Status; // 市场交易状态
		char EnterReason; // 进入交易状态
		uint32_t TradingUnit; //交易手单位（股票：100）
		uint32_t VolumeMultiple; //数量乘数
	} PRODUCTINFO, *PPRODUCTINFO;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, PRODUCT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, NAME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TYPE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, PRE_TRADE_TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_COUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_FROM1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_TO1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_FROM2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_TO2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_FROM3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_TO3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_FROM4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADE_TIME_TO4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, STATUS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, ENTER_REASON);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, TRADING_UNIT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, PRODUCT, VOLUME_MULTIPLE);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, PRODUCT, 18);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, PRODUCT);

	typedef struct tagCodeInfo
	{
		char Exchange[MAX_EXCHANGE_LENGTH + 1];
		char Product[MAX_PRODUCT_LENGTH + 1];
		char Code[MAX_CODE_LENGTH + 1];
		char Name[MAX_NAME_LENGTH + 1];
		char TradeCode[MAX_CODE_LENGTH + 1]; //交易代码
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSSsss
		char Status; //市场交易状态
		char EnterReason; //进入交易状态
		double PriceTick; //最小变动价位
		double YClose; //昨收
		double YSettle; //昨结
		double Settle; //结算价
		double Upper; //涨停板价
		double Lower; //跌停板价
		double Open;
		double High;
		double Low;
		double Close; // 交易价格，当然也是最新价，单位：元
		double Amount; // 总额
		double Volume; // 总成交量，单位：最小单位(股，张等)
		double Bid1; //申买价
		double Bid2; //申买价
		double Bid3; //申买价
		double Bid4; //申买价
		double Bid5; //申买价
		double BidV1; //申买量
		double BidV2; //申买量
		double BidV3; //申买量
		double BidV4; //申买量
		double BidV5; //申买量
		double Ask1; //申卖价
		double Ask2; //申卖价
		double Ask3; //申卖价
		double Ask4; //申卖价
		double Ask5; //申卖价
		double AskV1; //申卖量
		double AskV2; //申卖量
		double AskV3; //申卖量
		double AskV4; //申卖量
		double AskV5; //申卖量
	}CODEINFO, *PCODEINFO;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, PRODUCT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, NAME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, TRADE_CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, STATUS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ENTER_REASON);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, PRICETICK);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, YCLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, YSETTLE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, SETTLE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, UPPER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, LOWER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, OPEN);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, HIGH);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, LOW);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BID1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BID2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BID3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BID4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BID5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BIDV1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BIDV2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BIDV3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BIDV4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, BIDV5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASK1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASK2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASK3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASK4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASK5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASKV1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASKV2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASKV3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASKV4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, CODE, ASKV5);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, CODE, 41);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, CODE);

	//明细结构
	enum
	{
		ZQDB_CODE_TICK_FLAG_NONE, //
		ZQDB_CODE_TICK_FLAG_BOUGHT = 0x01, //外盘
		ZQDB_CODE_TICK_FLAG_SOLD = 0x02, //内盘
	};
	typedef struct tagCodeTick
	{
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSSsss
		uint32_t Flags; //
		double Close; // 交易价格，当然也是最新价，单位：元，放大PriceRate倍
		double Amount; // 现额
		double Volume; // 成交量(现量)，单位：最小单位(股，张等)
	} TICK, *PTICK;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TICK, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TICK, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TICK, FLAGS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TICK, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TICK, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TICK, VOLUME);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, TICK, 6);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, TICK);

	typedef struct tagCodeHistory
	{
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSS
		double Open; // 开盘价，单位：元(针对大盘指数表示开盘指数)，放大PriceRate倍
		double High; // 最高价，单位：元(针对大盘指数表示最高指数)，放大PriceRate倍
		double Low; // 最低价，单位：元(针对大盘指数表示最低指数)，放大PriceRate倍
		double Close; // 收盘价，单位：元(针对大盘指数表示收盘指数)，放大PriceRate倍
		double Amount; // 成交金额，单位：元
		double Volume; // 成交量，单位：最小单位(如股、张等)
	} KDATA, *PKDATA, BAR, *PBAR;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, OPEN);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, HIGH);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, LOW);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, KDATA, VOLUME);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, KDATA, 8);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, KDATA);

	////

	//UserID 可以有多个InvestorID InvestorID跟投资相关
	//UserID 可以有多个AccountID AccountID跟资金相关

#define ZQDB_USER_BROKER_REAL "REAL" //实盘交易BROKER
#define ZQDB_USER_BROKER_MOCK "MOCK" //模拟交易BROKER
#define ZQDB_USER_BROKER_TEST "TEST" //测试交易BROKER

	//所有USER结构体都要以tagUserBaseInfo开头
	struct tagUserBaseInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
	};

	///用户信息
	struct tagUserInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
		char Status; //用户状态 USER_STATUS_OFFLINE
	};
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, USER, BROKER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, USER, USER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, USER, STATUS);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, USER, 3);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, USER);

	///投资者信息
	struct tagInvestorInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
		char Investor[MAX_CODE_LENGTH + 1]; //投资者代码
		char InvestorName[MAX_NAME_LENGTH + 1]; //投资者名称
	};
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, INVESTOR, BROKER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, INVESTOR, USER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, INVESTOR, INVESTOR);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, INVESTOR, INVESTOR_NAME);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, INVESTOR, 4);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, INVESTOR);

	///资金账户信息
	struct tagAccountInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
		char Account[MAX_CODE_LENGTH + 1]; //投资者帐号
	};
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ACCOUNT, BROKER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ACCOUNT, USER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ACCOUNT, ACCOUNT);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, ACCOUNT, 3);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, ACCOUNT);

	///持仓信息
	struct tagPositionInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
		char Investor[MAX_CODE_LENGTH + 1]; //投资者代码
		char Exchange[MAX_EXCHANGE_LENGTH + 1]; //市场
		char Code[MAX_CODE_LENGTH + 1]; //代码
		char Currency; //币种 CURRENCY_CNY
		double Price; //价格
		double Volume;  //量
		double YVolume;  //昨量
		double FrozenVolume; //冻结量
		char Direction; //持仓方向 DIRECTION_LONG
		double Profit; //持仓盈亏
	};
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, BROKER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, USER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, INVESTOR);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, CURRENCY);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, PRICE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, YVOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, FROZEN_VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, DIRECTION);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, POSITION, PROFIT);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, POSITION, 12);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, POSITION);

	///订单信息
	struct tagOrderInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
		char Investor[MAX_CODE_LENGTH + 1]; //投资者代码
		char Order[MAX_ORDER_LENGTH + 1]; //订单ID
		char Exchange[MAX_EXCHANGE_LENGTH + 1]; //市场
		char Code[MAX_CODE_LENGTH + 1]; //代码
		uint32_t InsertTime;
		uint32_t UpdateTime;
		char Currency; //币种 CURRENCY_CNY
		double Price; //价格
		double Volume; //量
		double LeaveVolume; //剩余量
		char Direction; //订单方向 DIRECTION_LONG
		char Offset; //开平标志 OFFSET_OPEN
		char Type; //订单类型 ORDER_LIMIT
		char Status; //订单状态 ORDER_STATUS_SUBMITTING
	};
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, BROKER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, USER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, INVESTOR);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, ORDER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, INSERT_TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, UPDATE_TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, CURRENCY);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, PRICE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, LEAVE_VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, DIRECTION);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, OFFSET);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, TYPE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, ORDER, STATUS);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, ORDER, 16);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, ORDER);

	///成交信息
	struct tagTradeInfo
	{
		char Broker[MAX_CODE_LENGTH + 1]; //经纪公司代码
		char User[MAX_CODE_LENGTH + 1]; //用户代码
		char Investor[MAX_CODE_LENGTH + 1]; //投资者代码
		char Order[MAX_CODE_LENGTH + 1]; //订单ID
		char Trade[MAX_CODE_LENGTH + 1]; //成交ID
		char Exchange[MAX_EXCHANGE_LENGTH + 1]; //市场
		char Code[MAX_CODE_LENGTH + 1]; //代码
		uint32_t TradeTime;
		char Currency; //币种 CURRENCY_CNY	
		double Price; //价格
		double Volume; //量
		char Direction; //订单方向 DIRECTION_LONG
		char Offset; //开平标志 OFFSET_OPEN
		char Type; //成交类型 
	};
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, BROKER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, USER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, INVESTOR);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, ORDER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, TRADE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, TRADE_TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, CURRENCY);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, PRICE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, DIRECTION);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, OFFSET);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, TRADE, TYPE);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, TRADE, 14);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, TRADE);

	///
	//Stock 股票定义
	///

	typedef struct tagStockCodeInfo
	{
		char Exchange[MAX_EXCHANGE_LENGTH + 1];
		char Product[MAX_PRODUCT_LENGTH + 1];
		char Code[MAX_CODE_LENGTH + 1];
		char Name[MAX_NAME_LENGTH + 1];
		char TradeCode[MAX_CODE_LENGTH + 1]; //交易代码
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSSsss
		char Status; //市场交易状态
		char EnterReason; //进入交易状态
		double PriceTick; //最小变动价位
		double YClose; //昨收
		double YSettle; //昨结
		double Settle; //结算价
		double Upper; //涨停板价
		double Lower; //跌停板价
		double Open;
		double High;
		double Low;
		double Close; // 交易价格，当然也是最新价，单位：元
		double Amount; // 总额
		double Volume; // 总成交量，单位：最小单位(股，张等)
		double Bid1; //申买价
		double Bid2; //申买价
		double Bid3; //申买价
		double Bid4; //申买价
		double Bid5; //申买价
		double BidV1; //申买量
		double BidV2; //申买量
		double BidV3; //申买量
		double BidV4; //申买量
		double BidV5; //申买量
		double Ask1; //申卖价
		double Ask2; //申卖价
		double Ask3; //申卖价
		double Ask4; //申卖价
		double Ask5; //申卖价
		double AskV1; //申卖量
		double AskV2; //申卖量
		double AskV3; //申卖量
		double AskV4; //申卖量
		double AskV5; //申卖量

		//
		double TotalValue; //总市值
		double MarketValue; //流市市值
		double PB; //市净率
		double PE_TTM; //滚动市盈率
	}STKCODEINFO, *PSTKCODEINFO;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, PRODUCT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, NAME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, TRADE_CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, STATUS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ENTER_REASON);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, PRICETICK);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, YCLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, YSETTLE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, SETTLE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, UPPER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, LOWER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, OPEN);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, HIGH);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, LOW);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BID1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BID2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BID3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BID4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BID5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BIDV1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BIDV2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BIDV3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BIDV4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, BIDV5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASK1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASK2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASK3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASK4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASK5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASKV1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASKV2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASKV3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASKV4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, ASKV5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, TotalValue);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, MarketValue);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, PB);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, STKCODE, PE_TTM);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, STKCODE, 45);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, STKCODE);

	///
	//Futures 期货定义
	///

	typedef struct tagFuturesCodeInfo
	{
		char Exchange[MAX_EXCHANGE_LENGTH + 1];
		char Product[MAX_PRODUCT_LENGTH + 1];
		char Code[MAX_CODE_LENGTH + 1];
		char Name[MAX_NAME_LENGTH + 1];
		char TradeCode[MAX_CODE_LENGTH + 1]; //交易代码
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSSsss
		char Status; //市场交易状态
		char EnterReason; //进入交易状态
		double PriceTick; //最小变动价位
		double YClose; //昨收
		double YSettle; //昨结
		double Settle; //结算价
		double Upper; //涨停板价
		double Lower; //跌停板价
		double Open;
		double High;
		double Low;
		double Close; // 交易价格，当然也是最新价，单位：元
		double Amount; // 总额
		double Volume; // 总成交量，单位：最小单位(股，张等)
		double Bid1; //申买价
		double Bid2; //申买价
		double Bid3; //申买价
		double Bid4; //申买价
		double Bid5; //申买价
		double BidV1; //申买量
		double BidV2; //申买量
		double BidV3; //申买量
		double BidV4; //申买量
		double BidV5; //申买量
		double Ask1; //申卖价
		double Ask2; //申卖价
		double Ask3; //申卖价
		double Ask4; //申卖价
		double Ask5; //申卖价
		double AskV1; //申卖量
		double AskV2; //申卖量
		double AskV3; //申卖量
		double AskV4; //申卖量
		double AskV5; //申卖量

		///昨持仓量
		double PreOpenInterest;
		///持仓量
		double OpenInterest;

	}FTCODEINFO, *PFTCODEINFO;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, EXCHANGE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, PRODUCT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, NAME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, TRADE_CODE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, STATUS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ENTER_REASON);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, PRICETICK);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, YCLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, YSETTLE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, SETTLE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, UPPER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, LOWER);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, OPEN);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, HIGH);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, LOW);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BID1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BID2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BID3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BID4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BID5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BIDV1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BIDV2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BIDV3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BIDV4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, BIDV5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASK1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASK2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASK3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASK4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASK5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASKV1);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASKV2);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASKV3);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASKV4);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, ASKV5);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, PreOpenInterest);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTCODE, OpenInterest);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, FTCODE, 43);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, FTCODE);

	//明细结构
	typedef struct tagFutresTick
	{
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSSsss
		uint32_t Flags; //
		double Close; // 交易价格，当然也是最新价，单位：元，放大PriceRate倍
		double Amount; // 现额
		double Volume; // 成交量(现量)，单位：最小单位(股，张等)
		double OpenInterest; //持仓量
	} FTTICK, *PFTTICK;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, FLAGS);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTTICK, OpenInterest);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, FTTICK, 7);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, FTTICK);

	typedef struct tagFutresHistory
	{
		uint32_t Date; // YYYYMMDD
		uint32_t Time; // HHMMSS
		double Open; // 开盘价，单位：元(针对大盘指数表示开盘指数)，放大PriceRate倍
		double High; // 最高价，单位：元(针对大盘指数表示最高指数)，放大PriceRate倍
		double Low; // 最低价，单位：元(针对大盘指数表示最低指数)，放大PriceRate倍
		double Close; // 收盘价，单位：元(针对大盘指数表示收盘指数)，放大PriceRate倍
		double Amount; // 成交金额，单位：元
		double Volume; // 成交量，单位：最小单位(如股、张等)
		double OpenInterest; //持仓量
	} FTKDATA, *PFTKDATA, FTBAR, *PFTBAR;
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, DATE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, TIME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, OPEN);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, HIGH);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, LOW);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, CLOSE);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, AMOUNT);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, VOLUME);
	DECLARE_MDB_FIELD(ZQDB_API_EXPORT, ZQDB, FTKDATA, OpenInterest);
	DECLARE_MDB_FIELD_TABLE(ZQDB_API_EXPORT, ZQDB, FTKDATA, 9);
	DECLARE_MDB_FIELD_NAME_TABLE(ZQDB_API_EXPORT, ZQDB, FTKDATA);

	////

	//自定义产品表信息
	typedef struct tagSelfProductInfo
	{
		char name[MAX_NAME_LENGTH + 1]; //名称
	}SELFPRODUCTINFO, *PSELFPRODUCTINFO;

	//自选表信息
	typedef struct tagSelfselInfo
	{
		char name[MAX_NAME_LENGTH + 1]; //名称
	}SELFSELINFO, *PSELFSELINFO;

	ZQDB_API_EXPORT bool ZQDBProductCombine(const char* exchange, const char* product, char* dst);
	ZQDB_API_EXPORT bool ZQDBProductSplit(const char* src, char* exchange, char* product);

	ZQDB_API_EXPORT bool ZQDBCodeCombine(const char* exchange, const char* code, char* dst);
	ZQDB_API_EXPORT bool ZQDBCodeSplit(const char* src, char* exchange, char* code);

	ZQDB_API_EXPORT bool ZQDBIsBaseCycle(PERIODTYPE cycle);
	ZQDB_API_EXPORT PERIODTYPE ZQDBCalcBaseCycle(PERIODTYPE cycle, size_t cycleex, size_t* multiple);
	ZQDB_API_EXPORT size_t ZQDBCycle2Second(PERIODTYPE cycle, size_t cycleex);
	ZQDB_API_EXPORT const char* ZQDBCycle2Str(PERIODTYPE cycle);
	ZQDB_API_EXPORT char* ZQDBStrCycle(char* str, PERIODTYPE cycle, size_t cycleex);

#define ZQDB_HOLIDAY_FLAG_INCLUDE_WEEKEND 0x01
	ZQDB_API_EXPORT void ZQDBWriteHolidayFile(const char* file, uint32_t* date, size_t count, size_t flags);
	
	ZQDB_API_EXPORT HZQDB ZQDBFindHoliday(const char* exchange);

	ZQDB_API_EXPORT bool ZQDBIsWeekend(uint32_t date);
	ZQDB_API_EXPORT bool ZQDBIsTradeDay(HZQDB h, uint32_t date);
	ZQDB_API_EXPORT uint32_t ZQDBNextTradeDay(HZQDB h, uint32_t date, uint32_t offset);
	ZQDB_API_EXPORT uint32_t ZQDBPrevTradeDay(HZQDB h, uint32_t date, uint32_t offset);

	////开盘价必须有效
	//ZQDB_API_EXPORT bool ZQDBIsInvalidPrice(double open);
	//ZQDB_API_EXPORT bool ZQDBIsInvalidPrice2(double open, double close);
	//ZQDB_API_EXPORT bool ZQDBIsInvalidPrice4(double open, double high, double low, double close);

	ZQDB_API_EXPORT const char* ZQDBCurrency2Str(char currency);
	ZQDB_API_EXPORT const char* ZQDBOrderStatus2Str(char status);
	ZQDB_API_EXPORT const char* ZQDBOrderType2Str(char type);
	ZQDB_API_EXPORT const char* ZQDBDirectionType2Str(char type);
	ZQDB_API_EXPORT const char* ZQDBOffsetType2Str(char type);

	ZQDB_API_EXPORT bool ZQDBOrderIsFinal(char status);

	ZQDB_API_EXPORT int ZQDBCompareCycle(uint32_t olddate, uint32_t newdate, uint32_t oldtime, uint32_t newtime, PERIODTYPE cycle, size_t cycleex);

	ZQDB_API_EXPORT bool ZQDBSameCycle(uint32_t olddate, uint32_t newdate, uint32_t oldtime, uint32_t newtime, PERIODTYPE cycle, size_t cycleex);
	
	ZQDB_API_EXPORT size_t ZQDBGetCategoryCount();
	ZQDB_API_EXPORT size_t ZQDBGetCategory(HZQDB* h, size_t count);

	ZQDB_API_EXPORT void ZQDBRemoveCategory(const char* name);
	ZQDB_API_EXPORT HZQDB ZQDBOpenOrCreateCategory(const char* name, ZQDB_HANDLE_TYPE type);
	ZQDB_API_EXPORT HZQDB ZQDBOpenCategory(const char* name);
	ZQDB_API_EXPORT void ZQDBRefCategory(HZQDB h);
	ZQDB_API_EXPORT void ZQDBCloseCategory(HZQDB h);

	ZQDB_API_EXPORT HZQDB ZQDBGetCategoryParent(HZQDB h);
	ZQDB_API_EXPORT const char* ZQDBGetCategoryName(HZQDB h);
	ZQDB_API_EXPORT ZQDB_HANDLE_TYPE ZQDBGetCategoryType(HZQDB h);

	ZQDB_API_EXPORT void ZQDBClearCategory(HZQDB h);
	ZQDB_API_EXPORT HZQDB ZQDBAppendCategory(HZQDB h, const char* name, ZQDB_HANDLE_TYPE type);
	ZQDB_API_EXPORT size_t ZQDBAppendCategorySeparator(HZQDB h);
	ZQDB_API_EXPORT size_t ZQDBAppendCategoryValue(HZQDB h, HZQDB elem);
	ZQDB_API_EXPORT size_t ZQDBAppendCategoryValueEx(HZQDB h, HZQDB* elem, size_t count);
	ZQDB_API_EXPORT size_t ZQDBGetCategoryValueCount(HZQDB h);
	ZQDB_API_EXPORT size_t ZQDBGetCategoryValue(HZQDB h, HZQDB* elem, size_t count);
	ZQDB_API_EXPORT HZQDB ZQDBFindCategoryValue(HZQDB h, const char* name);

	ZQDB_API_EXPORT const char* ZQDBGetMarketDir();

	ZQDB_API_EXPORT MDB_STATUS ZQDBBeginNewTradingDay(const char* exchange, uint32_t flags);
	//具体更新由对应模块自行实现，基本上是等待一下，先清理数据（Tick、M1、M5等历史数据），然后更新市场、产品、代码等快照数据
	ZQDB_API_EXPORT void ZQDBDoNewTradingDayClear(const char* exchange, uint32_t flags);
	ZQDB_API_EXPORT void ZQDBEndNewTradingDay(const char* exchange, uint32_t flags);

	ZQDB_API_EXPORT HZQDB ZQDBUpdateOrInitExchange(EXCHANGEINFO* exchange);
	ZQDB_API_EXPORT HZQDB ZQDBUpdateOrInitProductTable(MDB_FIELD* field, size_t field_num, HZQDB exchange, size_t max_count);
	ZQDB_API_EXPORT HZQDB ZQDBUpdateOrInitProduct(HZQDB exchange, PRODUCTINFO* product);
	ZQDB_API_EXPORT HZQDB ZQDBUpdateOrInitCodeTable(MDB_FIELD* field, size_t field_num, HZQDB product, size_t max_count);
	ZQDB_API_EXPORT HZQDB ZQDBUpdateOrInitCode(HZQDB product, CODEINFO* code);

	ZQDB_API_EXPORT HZQDB ZQDBGetExchange(const char* exchange);
	ZQDB_API_EXPORT HZQDB ZQDBGetProduct(const char* product, const char* exchange);
	ZQDB_API_EXPORT HZQDB ZQDBGetCode(const char* code, const char* exchange);
	ZQDB_API_EXPORT size_t ZQDBGetCodeByTradeCode(HZQDB hmodule, const char* code, HZQDB* h, size_t hcount);

#define ZQDB_CODE_DATA_THREAD_MAIN 0 //主线程数据
	ZQDB_API_EXPORT void* ZQDBGetData(HZQDB h, uint8_t index);
	ZQDB_API_EXPORT void ZQDBSetData(HZQDB h, uint8_t index, void* data);

	enum MarketDataSource {
		MARKET_DATA_SOURCE_DEFAULT = 0, //默认行情源
		MARKET_DATA_SOURCE_1, //行情源1
		MARKET_DATA_SOURCE_2, //行情源2
		MARKET_DATA_SOURCE_3, //行情源3
	};
	ZQDB_API_EXPORT MarketDataSource ZQDBGetMarketDataSource();
	ZQDB_API_EXPORT void ZQDBSetMarketDataSource(MarketDataSource source);

	ZQDB_API_EXPORT bool ZQDBIsSubscribeMarketDataAll(HZQDB h);
	ZQDB_API_EXPORT bool ZQDBIsSubscribeMarketData(HZQDB h);
	ZQDB_API_EXPORT void ZQDBSubscribeMarketData(HZQDB h);
	ZQDB_API_EXPORT void ZQDBUnSubscribeMarketData(HZQDB h);
	//ZQDB_API_EXPORT void ZQDBSubUnSubscribeMarketData(HZQDB* subs, size_t sub_count, HZQDB* unsubs, size_t unsub_count);

	ZQDB_API_EXPORT void ZQDBRequestMarketData(HZQDB* hs, size_t h_count, size_t* ids, size_t id_count);

	ZQDB_API_EXPORT bool ZQDBIsMarketDataValid(HZQDB h, bool depth);
	ZQDB_API_EXPORT size_t ZQDBGetPriceDigits(HZQDB h);
	ZQDB_API_EXPORT double ZQDBGetYClose(HZQDB h, bool yclose);

	//0:平盘 1:外盘 -1:内盘
	ZQDB_API_EXPORT char ZQDBIsBoughtSold(double BidPrice, double AskPrice, double NowPrice);

#define UPDATE_MARKET_DATA_FLAG_INIT 0X0001
	ZQDB_API_EXPORT void ZQDBUpdateMarketData(HZQDB h, MDB_FIELD* fields, size_t field_num, void* data, size_t flags);

	ZQDB_API_EXPORT bool ZQDBIsAnyDataExist(HZQDB h);
	ZQDB_API_EXPORT bool ZQDBIsDataExist(HZQDB h, PERIODTYPE base_cycle);
	ZQDB_API_EXPORT void ZQDBUpdateOrInitTickData(HZQDB h, MDB_FIELD* field, size_t field_num, const TICK* data, size_t elem_num, size_t max_elem_num);
	ZQDB_API_EXPORT void ZQDBUpdateOrInitKData(HZQDB h, PERIODTYPE base_cycle, MDB_FIELD* field, size_t field_num, const KDATA* data, size_t elem_num, size_t max_elem_num);
	ZQDB_API_EXPORT void ZQDBAddTickData(HZQDB h, const TICK* data, size_t data_sz);
	ZQDB_API_EXPORT void ZQDBAddKData(HZQDB h, PERIODTYPE base_cycle, const KDATA* data, size_t data_sz);
	ZQDB_API_EXPORT void ZQDBUpdateKData(HZQDB h, PERIODTYPE base_cycle, const KDATA* data, size_t data_sz);

	ZQDB_API_EXPORT double ZQDBGetPriceByTickTime(HZQDB h, uint32_t date, uint32_t time);

	//ZQDB_API_EXPORT void ZQDBDataLock(HZQDB h, PERIODTYPE cycle, bool shared);
	//ZQDB_API_EXPORT void ZQDBDataUnLock(HZQDB h, PERIODTYPE cycle, bool shared);

	ZQDB_API_EXPORT size_t ZQDBGetDataAttrCount(HZQDB h, PERIODTYPE base_cycle);
	ZQDB_API_EXPORT const MDB_FIELD* ZQDBGetDataAttr(HZQDB h, PERIODTYPE base_cycle);

	//ZQDB_API_EXPORT bool ZQDBIsTradeTimeCrossDay(uint16_t TradeTime[][2], uint8_t TradeTimeCount);
	//ZQDB_API_EXPORT bool ZQDBIsTimePointCrossDay(uint16_t TimePoint, uint16_t TradeTime[][2], uint8_t TradeTimeCount);

	//ZQDB_API_EXPORT size_t ZQDBGetMaxTimePoint(uint16_t TradeTime[][2], uint8_t TradeTimeCount);
	//ZQDB_API_EXPORT uint32_t ZQDBGetHHMMSSByTimePoint(uint16_t TimePoint, uint16_t TradeTime[][2], uint8_t TradeTimeCount);
	//ZQDB_API_EXPORT uint16_t ZQDBGetTimePointByHHMMSS(uint32_t HHMMSS, uint16_t TradeTime[][2], uint8_t TradeTimeCount);

	ZQDB_API_EXPORT size_t ZQDBGetTradeTimeCount(HZQDB h);
	ZQDB_API_EXPORT int ZQDBGetTradeCrossDayPos(HZQDB h);
	//ZQDB_API_EXPORT size_t ZQDBGetTimePointCount(HZQDB h, PERIODTYPE base_cycle, size_t pos);
	ZQDB_API_EXPORT size_t ZQDBGetMaxTimePointCount(HZQDB h, PERIODTYPE cycle, size_t cycleex);
	ZQDB_API_EXPORT size_t ZQDBGetTimeByTimePoint(HZQDB h, uint32_t tradeday, size_t TimePoint, PERIODTYPE cycle, size_t cycleex, uint32_t* date);
	ZQDB_API_EXPORT uint32_t ZQDBGetTimeByTime(HZQDB h, uint32_t time, PERIODTYPE cycle, size_t cycleex, uint32_t* date);
	ZQDB_API_EXPORT int ZQDBIsNotInTradeTime(HZQDB h, uint32_t time, size_t* pos, uint32_t* date);
	ZQDB_API_EXPORT size_t ZQDBGetTimePointByTime(HZQDB h, uint32_t time, int cmp, size_t pos, PERIODTYPE cycle, size_t cycleex);
	
	ZQDB_API_EXPORT uint32_t ZQDBGetTradeDay(HZQDB h, uint32_t date, uint32_t time);
	ZQDB_API_EXPORT uint32_t ZQDBGetOpenDate(HZQDB h, uint32_t tradeday, size_t pos);
	ZQDB_API_EXPORT uint32_t ZQDBGetCloseDate(HZQDB h, uint32_t tradeday, size_t pos);
	ZQDB_API_EXPORT uint32_t ZQDBGetOpenTime(HZQDB h, uint32_t* date, size_t pos);
	ZQDB_API_EXPORT uint32_t ZQDBGetCloseTime(HZQDB h, uint32_t* date, size_t pos);
	ZQDB_API_EXPORT uint32_t ZQDBGetNowTime(HZQDB h, uint32_t* date, uint32_t* tradeday);
	//返回datetime是否在交易时间段内，-1小于交易时间(盘前)，1大于交易时间（盘后），0交易时间内（盘中）
	ZQDB_API_EXPORT int ZQDBIsNotInTradingTime(HZQDB h, uint32_t date, uint32_t time, size_t* pos);
	
	//比较更新判断，判断是更新旧周期还是新增周期
	//ZQDB_API_EXPORT bool ZQDBSameCycleEx(HZQDB h, uint32_t olddate, uint32_t newdate, uint32_t oldtime, uint32_t newtime, PERIODTYPE cycle, size_t cycleex);
	//ZQDB_API_EXPORT bool ZQDBSameCycleTradingTime(HZQDB h, uint32_t olddate, uint32_t newdate, uint32_t oldtime, uint32_t newtime, PERIODTYPE cycle, size_t cycleex);

	ZQDB_API_EXPORT bool ZQDBSyncExchange(HZQDB h);
	ZQDB_API_EXPORT bool ZQDBSyncProduct(HZQDB h);
	ZQDB_API_EXPORT bool ZQDBSyncCode(HZQDB h);

	ZQDB_API_EXPORT bool ZQDBExistData(HZQDB h, PERIODTYPE cycle);
	ZQDB_API_EXPORT bool ZQDBSaveData(HZQDB h, PERIODTYPE cycle, ZQDB_MSG* msg);

	ZQDB_API_EXPORT void ZQDBReserveData(HZQDB h, PERIODTYPE cycle, size_t max_num);

	ZQDB_API_EXPORT void ZQDBRemoveData(HZQDB h, PERIODTYPE cycle, size_t pos, size_t num);
	
	ZQDB_API_EXPORT bool ZQDBRequestData(HZQDB h, PERIODTYPE base_cycle, ZQDB_MSG** rsp, size_t timeout);
	ZQDB_API_EXPORT bool ZQDBRequestDataCB(HZQDB h, PERIODTYPE base_cycle, ZQDB_REQUEST_CB cb, void* user_data);

	ZQDB_API_EXPORT size_t ZQDBGetDataMaxCount(HZQDB h, PERIODTYPE base_cycle);
	ZQDB_API_EXPORT size_t ZQDBGetDataCount(HZQDB h, PERIODTYPE base_cycle, size_t* elem_sz);
	ZQDB_API_EXPORT void* ZQDBGetDataValue(HZQDB h, PERIODTYPE base_cycle, MDB_FIELD* field);

#define ZQDB_DATA_FLAG_NO_UPDATE_DATA 0X00000001 //不更新数据（默认实时更新数据）
#define ZQDB_DATA_FLAG_SYNC_DATA 0X00000002 //同步数据
#define ZQDB_DATA_FLAG_ASYNC_DATA 0X00000004 //异步同步数据
#define ZQDB_DATA_FLAG_LOAD_DATA 0X00000008 //本地加载数据
#define ZQDB_DATA_FLAG_FORWARD_DATA 0x00000010 //前复权数据
#define ZQDB_DATA_FLAG_BACKWARD_DATA 0x00000020 //后复权数据
#define ZQDB_DATA_FLAG_MASK 0X0000FFFF //
	ZQDB_API_EXPORT HZQDB ZQDBDataOpen(HZQDB code, PERIODTYPE cycle, size_t cycleex, size_t flags);
	ZQDB_API_EXPORT void ZQDBDataRef(HZQDB data);
	ZQDB_API_EXPORT void ZQDBDataClose(HZQDB data);
	ZQDB_API_EXPORT HZQDB ZQDBDataGetCode(HZQDB data);
	ZQDB_API_EXPORT PERIODTYPE ZQDBDataGetCycle(HZQDB data, size_t* cycleex);
	ZQDB_API_EXPORT void* ZQDBDataGetFieldValue(HZQDB data, MDB_FIELD* field);
	ZQDB_API_EXPORT bool ZQDBDataIsInit(HZQDB data);
	ZQDB_API_EXPORT size_t ZQDBDataGetAttrCount(HZQDB data);
	ZQDB_API_EXPORT const MDB_FIELD* ZQDBDataGetAttr(HZQDB data);
	ZQDB_API_EXPORT size_t ZQDBDataGetMaxCount(HZQDB data);
	ZQDB_API_EXPORT size_t ZQDBDataGetCount(HZQDB data, size_t* elem_sz);
	ZQDB_API_EXPORT void* ZQDBDataGetValue(HZQDB data, MDB_FIELD* field);
	ZQDB_API_EXPORT void ZQDBDataInit(HZQDB data, MDB_FIELD* field, size_t field_num, size_t max_count);
	ZQDB_API_EXPORT void ZQDBDataReserveCount(HZQDB data, size_t max_count);
	ZQDB_API_EXPORT void ZQDBDataSetCount(HZQDB data, size_t count);
	ZQDB_API_EXPORT void ZQDBDataRemoveValue(HZQDB data, size_t num);


	//
	//ZQDB_API_EXPORT size_t ZQDBGetAllModuleCount();
	//ZQDB_API_EXPORT size_t ZQDBGetAllModule(HZQDB* module, size_t count);

	//交易日切换清理标志
	enum {
		CLEAR_MARKET_DATA = 0X0001,
		SAVE_MARKET_DATA = 0X0002,
		CLEAR_TRADE_DATA = 0X0100,
		SAVE_TRADE_DATA = 0X0200,
	};
	ZQDB_API_EXPORT MDB_STATUS ZQDBBeginModuleNewTradingDay(HZQDB module, uint32_t flags);
	//具体更新由对应模块自行实现，基本上是等待一下，先清理数据（委托、持仓、成交等数据），然后更新委托、持仓、成交等数据
	ZQDB_API_EXPORT void ZQDBDoModuleNewTradingDayClear(HZQDB module, uint32_t flags);
	ZQDB_API_EXPORT void ZQDBEndModuleNewTradingDay(HZQDB module, uint32_t flags);
	
	//刷新数据，主要是支持非推送模块刷新实时数据
	//h是指具体刷新对象，可以是模块、用户、持仓、委托、成交等等
	//millis指定刷新毫秒间隔，0表示只刷新一次， 小于0表示停止刷新
	//flags指定刷新标志，默认填0
#define ZQDB_REFRESH_FLAG_FIND_RESULT 0x00000001 //会生成刷新ID
	ZQDB_API_EXPORT size_t ZQDBRefresh(HZQDB h, ssize_t millis, size_t flags);
	ZQDB_API_EXPORT void ZQDBRefreshed(size_t id); //刷新完成
	ZQDB_API_EXPORT bool ZQDBIsRefreshed(size_t id); //判断是否刷新完成

	ZQDB_API_EXPORT size_t ZQDBIsRecording();
#if USE_LOG_FILE
	typedef union tagZQDBRecordHead {
		//uint32_t date; //YYYYMMDD
		uint32_t time : 24; //HHMMSS
		uint32_t type : 8;
	}ZQDBRECORDHEAD;
	typedef struct tagZQDBRecordBuf {
		const char* buf;
		uint32_t len;
	}ZQDBRECORDBUF;
	ZQDB_API_EXPORT bool ZQDBWriteRecordData(HZQDB h, const tagZQDBRecordHead* head, const tagZQDBRecordBuf* data, uint8_t count);

	ZQDB_API_EXPORT size_t ZQDBGetRecordCount();
	ZQDB_API_EXPORT size_t ZQDBGetRecordDate(size_t pos);
	ZQDB_API_EXPORT MDB_STATUS ZQDBDeleteRecord(size_t date);
#endif

	ZQDB_API_EXPORT size_t ZQDBIsTesting();
	ZQDB_API_EXPORT void ZQDBPauseTesting();
	ZQDB_API_EXPORT void ZQDBContinueTesting();

#pragma pack(pop)

#if defined(__cplusplus)
}

namespace zqdb {

	inline bool ProductCombine(const char* exchange, const char* product, char* dst) { return ZQDBProductCombine(exchange, product, dst); }
	inline bool ProductSplit(const char* src, char* exchange, char* product) { return ZQDBProductSplit(src, exchange, product); }

	inline bool CodeCombine(const char* exchange, const char* code, char* dst) { return ZQDBCodeCombine(exchange, code, dst); }
	inline bool CodeSplit(const char* src, char* exchange, char* code) { return ZQDBCodeSplit(src, exchange, code); }

	inline const char* Cycle2Str(PERIODTYPE cycle) { return ZQDBCycle2Str(cycle); }
	inline char* StrCycle(char* str, PERIODTYPE cycle, size_t cycleex = 0) { return ZQDBStrCycle(str, cycle, cycleex); }

	inline bool SameCycle(uint32_t olddate, uint32_t newdate, uint32_t oldtime, uint32_t newtime, PERIODTYPE cycle, size_t cycleex) { return ZQDBSameCycle(olddate, newdate, oldtime, newtime, cycle, cycleex); }
	
	///

	template<class T>
	class UserMap
	{
		typedef UserMap<T> This;
	protected:
		HZQDB user_ = nullptr;

	public:
		void OnUserChanged()
		{

		}

		void Clear()
		{
			user_ = nullptr;
		}
		bool IsOk() const { return user_ != nullptr; }
		HZQDB GetUser() const
		{
			return user_;
		}
		void SetUser(HZQDB user)
		{
			T* pT = static_cast<T*>(this);
			if (user_ != user) {
				user_ = user;
				pT->OnUserChanged();
			}
		}
	};

	template<class TInfo = tagExchangeInfo>
	class ExchangeT : public ObjectT<TInfo> {
		typedef ObjectT<TInfo> Base;
	public:
		ExchangeT(HZQDB h = nullptr) :Base(h) {}
		ExchangeT(const char* exchange) :Base(ZQDBGetExchange(exchange)) {}
		~ExchangeT() { }

		uint32_t GetOpenTime(uint32_t* date = nullptr, size_t pos = 0) { return ZQDBGetOpenTime(this->h_, date, pos); }
		uint32_t GetCloseTime(uint32_t* date = nullptr, size_t pos = (size_t)-1) { return ZQDBGetCloseTime(this->h_, date, pos); }
		uint32_t GetNowTime(uint32_t* date = nullptr, uint32_t* tradeday = nullptr) { return ZQDBGetNowTime(this->h_, date, tradeday); }
		int IsNotInTradingTime(uint32_t date, uint32_t time, size_t* pos = nullptr) { return ZQDBIsNotInTradingTime(this->h_, date, time, pos); }

		void UpdateMarketData(MDB_FIELD* fields, size_t field_num, void* data) { ZQDBUpdateMarketData(this->h_, fields, field_num, data); }

	};
	typedef ExchangeT<tagExchangeInfo> Exchange;

	template<class TInfo = tagProductInfo>
	class ProductT : public ObjectT<TInfo> {
		typedef ObjectT<TInfo> Base;
	public:
		ProductT(HZQDB h = nullptr) :Base(h) {}
		ProductT(const char* product, const char* exchange = nullptr) :Base(ZQDBGetProduct(product, exchange)) {}
		~ProductT() { }

		HZQDB GetExchange() { return ZQDBGetParent(this->h_); }

		uint32_t GetOpenTime(uint32_t* date = nullptr, size_t pos = 0) { return ZQDBGetOpenTime(this->h_, date, pos); }
		uint32_t GetCloseTime(uint32_t* date = nullptr, size_t pos = (size_t)-1) { return ZQDBGetCloseTime(this->h_, date, pos); }
		uint32_t GetNowTime(uint32_t* date = nullptr, uint32_t* tradeday = nullptr) { return ZQDBGetNowTime(this->h_, date, tradeday); }
		int IsNotInTradingTime(uint32_t date, uint32_t time, size_t* pos = nullptr) { return ZQDBIsNotInTradingTime(this->h_, date, time, pos); }

		void UpdateMarketData(MDB_FIELD* fields, size_t field_num, void* data) { ZQDBUpdateMarketData(this->h_, fields, field_num, data); }
	};
	typedef ProductT<tagProductInfo> Product;

	class Data
	{
	protected:
		HZQDB h_ = nullptr;
		bool auto_close_ = true;
	public:
		Data() {}
		Data(const char* code, PERIODTYPE cycle, size_t cycleex = 0, size_t flags = 0) :h_(ZQDBDataOpen(ZQDBGetCode(code, nullptr), cycle, cycleex, flags)) {}
		Data(const char* code, const char* exchange, PERIODTYPE cycle, size_t cycleex = 0, size_t flags = 0) :h_(ZQDBDataOpen(ZQDBGetCode(code, exchange), cycle, cycleex, flags)) {}
		Data(HZQDB code, PERIODTYPE cycle, size_t cycleex = 0, size_t flags = 0) :h_(ZQDBDataOpen(code, cycle, cycleex, flags)) {}
		Data(HZQDB h, bool ref = false) :h_(h), auto_close_(ref) {
			if (h_ && auto_close_) {
				ZQDBDataRef(h_);
			}
		}
		Data(const Data& o) {
			h_ = o.h_;
			auto_close_ = o.auto_close_;
			if (h_ && auto_close_) {
				ZQDBDataRef(h_);
			}
		}
		Data(Data&& o) {
			h_ = o.h_; o.h_ = nullptr;
			auto_close_ = o.auto_close_; o.auto_close_ = false;
		}
		Data& operator=(const Data& o)
		{
			if (this == &o) {
				return *this;
			}
			Close();
			h_ = o.h_;
			auto_close_ = o.auto_close_;
			if (h_ && auto_close_) {
				ZQDBDataRef(h_);
			}
			return *this;
		}
		Data& operator=(Data&& o)
		{
			if (this == &o) {
				return *this;
			}
			Close();
			h_ = o.h_; o.h_ = nullptr;
			auto_close_ = o.auto_close_; o.auto_close_ = false;
			return *this;
		}
		~Data()
		{
			Close();
		}

		inline void Close() {
			if (h_ && auto_close_) {
				ZQDBDataClose(h_);
				h_ = nullptr;
			}
		}
		inline HZQDB Open(HZQDB code, PERIODTYPE cycle, size_t cycleex = 0, size_t flags = 0) { h_ = ZQDBDataOpen(code, cycle, cycleex, flags);  auto_close_ = true; return h_; }
		inline bool IsOpen() { return h_ != nullptr; }
		inline operator bool() const { return h_ != nullptr; }
		inline operator HZQDB() const { return h_; }

		inline HZQDB GetCode() { return ZQDBDataGetCode(h_); }
		inline PERIODTYPE GetCycle(size_t* cycleex = nullptr) { return ZQDBDataGetCycle(h_, cycleex); }
		
		inline bool IsInit() { return ZQDBDataIsInit(h_); }
		
		inline void* GetFieldValue(const MDB_FIELD& field) { return ZQDBDataGetFieldValue(h_, &const_cast<MDB_FIELD&>(field)); }

		inline size_t GetAttrCount() { return ZQDBDataGetAttrCount(h_); }
		inline const MDB_FIELD* GetAttr() { return ZQDBDataGetAttr(h_); }
		inline size_t GetDataMaxCount() { return ZQDBDataGetMaxCount(h_); }
		inline size_t GetDataCount(size_t* elem_sz = nullptr) { return ZQDBDataGetCount(h_, elem_sz); }
		inline void* GetData(const MDB_FIELD& field) { return ZQDBDataGetValue(h_, &const_cast<MDB_FIELD&>(field)); }
	};

	template<class TInfo = tagCodeInfo>
	class CodeT : public ObjectT<TInfo> {
		typedef ObjectT<TInfo> Base;
	public:
		CodeT(HZQDB h = nullptr) :Base(h) {}
		CodeT(const char* code, const char* exchange = nullptr) :Base(ZQDBGetCode(code, exchange)) {}
		~CodeT() { }

		HZQDB GetExchange() { return ZQDBGetParent(ZQDBGetParent(this->h_)); }
		HZQDB GetProduct() { return ZQDBGetParent(this->h_); }
		
		bool IsSubscribeAll() { return ZQDBIsSubscribeMarketDataAll(this->h_); }
		bool IsSubscribe() { return ZQDBIsSubscribeMarketData(this->h_); }
		void Subscribe() { return ZQDBSubscribeMarketData(this->h_); }
		void UnSubscribe() { return ZQDBUnSubscribeMarketData(this->h_); }
		bool IsMarketValid(bool depth = true) { return ZQDBIsMarketDataValid(this->h_, depth); }

		uint32_t GetOpenTime(uint32_t* date = nullptr, size_t pos = 0) { return ZQDBGetOpenTime(this->h_, date, pos); }
		uint32_t GetCloseTime(uint32_t* date = nullptr, size_t pos = (size_t)-1) { return ZQDBGetCloseTime(this->h_, date, pos); }
		uint32_t GetNowTime(uint32_t* date = nullptr, uint32_t* tradeday = nullptr) { return ZQDBGetNowTime(this->h_, date, tradeday); }
		int IsNotInTradingTime(uint32_t date, uint32_t time, size_t* pos = nullptr) { return ZQDBIsNotInTradingTime(this->h_, date, time, pos); }

		void UpdateMarketData(MDB_FIELD* fields, size_t field_num, void* data) { ZQDBUpdateMarketData(this->h_, fields, field_num, data); }

		void UpdateOrInitTickData(MDB_FIELD* field, size_t field_num, const TICK* data, size_t max_count) { ZQDBUpdateOrInitTickData(this->h_, field, field_num, data, max_count); }
		void UpdateOrInitKData(PERIODTYPE base_cycle, MDB_FIELD* field, size_t field_num, const KDATA* data, size_t max_count) { ZQDBUpdateOrInitKData(this->h_, base_cycle, field, field_num, data, max_count); }
		void AddTickData(const TICK* data) { ZQDBAddTickData(this->h_, data); }
		void AddKData(PERIODTYPE base_cycle, const KDATA* data) { ZQDBAddKData(this->h_, base_cycle, data); }
		void UpdateKData(PERIODTYPE base_cycle, MDB_FIELD* field, size_t field_num, const KDATA* data) { ZQDBUpdateKData(this->h_, base_cycle, field, field_num, data); }

		size_t GetDataMaxCount(PERIODTYPE base_cycle) { return ZQDBGetDataMaxCount(this->h_, base_cycle); }
		size_t GetDataCount(PERIODTYPE base_cycle, size_t* elem_sz = nullptr) { return ZQDBGetDataCount(this->h_, base_cycle, elem_sz); }
		void* GetDataValue(PERIODTYPE base_cycle, const MDB_FIELD& field) { return ZQDBGetDataValue(this->h_, base_cycle, &const_cast<MDB_FIELD&>(field)); }
	};
	typedef CodeT<tagCodeInfo> Code;

	template<typename TCODEINFO = CODEINFO>
	inline double GetBidPrice(TCODEINFO* code, int level)
	{
		switch (level)
		{
		case 1: {
			return code->Bid1;
		} break;
		case 2: {
			return code->Bid2;
		} break;
		case 3: {
			return code->Bid3;
		} break;
		case 4: {
			return code->Bid4;
		} break;
		case 5: {
			return code->Bid5;
		} break;
		}
		return code->Close;
	}

	template<typename TCODEINFO = CODEINFO>
	inline double GetBidVolume(TCODEINFO* code, int level)
	{
		switch (level)
		{
		case 1: {
			return code->BidV1;
		} break;
		case 2: {
			return code->BidV2;
		} break;
		case 3: {
			return code->BidV3;
		} break;
		case 4: {
			return code->BidV4;
		} break;
		case 5: {
			return code->BidV5;
		} break;
		}
		return 0.;
	}

	template<typename TCODEINFO = CODEINFO>
	inline double GetAskPrice(TCODEINFO* code, int level)
	{
		switch (level)
		{
		case 1: {
			return code->Ask1;
		} break;
		case 2: {
			return code->Ask2;
		} break;
		case 3: {
			return code->Ask3;
		} break;
		case 4: {
			return code->Ask4;
		} break;
		case 5: {
			return code->Ask5;
		} break;
		}
		return code->Close;
	}

	template<typename TCODEINFO = CODEINFO>
	inline double GetAskVolume(TCODEINFO* code, int level)
	{
		switch (level)
		{
		case 1: {
			return code->AskV1;
		} break;
		case 2: {
			return code->AskV2;
		} break;
		case 3: {
			return code->AskV3;
		} break;
		case 4: {
			return code->AskV4;
		} break;
		case 5: {
			return code->AskV5;
		} break;
		}
		return 0.;
	}

	///

	class Category
	{
	private:
		HZQDB h_ = nullptr;
		bool ref_flag_ = false;
	public:
		Category() {}
		Category(HZQDB h, bool ref_flag = false) :h_(h), ref_flag_(ref_flag) {
			if (ref_flag_) {
				ZQDBRefCategory(this->h_);
			}
		}
		Category(const char* name, ZQDB_HANDLE_TYPE type) {
			OpenOrCreate(name, type);
		}
		Category(const char* name, HZQDB parent = nullptr) {
			Open(name, parent);
		}
		~Category() {
			Close();
		}
		Category(const Category& cat) {
			h_ = cat.h_;
			ref_flag_ = cat.ref_flag_;
			if (ref_flag_) {
				ZQDBRefCategory(this->h_);
			}
		}
		Category& operator=(const Category& cat) {
			Close();
			h_ = cat.h_;
			ref_flag_ = cat.ref_flag_;
			if (ref_flag_) {
				ZQDBRefCategory(this->h_);
			}
			return *this;
		}
		Category(Category&& cat) {
			h_ = cat.h_;
			cat.h_ = nullptr;
			ref_flag_ = cat.ref_flag_;
			cat.ref_flag_ = false;
		}
		Category& operator=(Category&& cat) {
			Close();
			h_ = cat.h_;
			cat.h_ = nullptr;
			ref_flag_ = cat.ref_flag_;
			cat.ref_flag_ = false;
			return *this;
		}

		inline operator bool() const { return h_ != nullptr; }
		inline operator HZQDB() const { return h_; }

		static size_t GetCategoryCount() { return ZQDBGetCategoryCount(); }
		static size_t GetCategory(HZQDB* h, size_t count) { return ZQDBGetCategory(h, count); }
		static void RemoveCategory(const char* name) { ZQDBRemoveCategory(name); }

		inline HZQDB OpenOrCreate(const char* name, ZQDB_HANDLE_TYPE type) {
			h_ = ZQDBOpenOrCreateCategory(name, type);
			ref_flag_ = h_ != nullptr;
			return h_;
		}
		inline HZQDB Open(const char* name, HZQDB parent = nullptr) {
			if (parent) {
				h_ = ZQDBFindCategoryValue(parent, name);
			}
			else {
				h_ = ZQDBOpenCategory(name);
			}
			ref_flag_ = h_ != nullptr;
			return h_;
		}
		inline void Close()
		{
			if (this->h_ && ref_flag_) {
				ZQDBCloseCategory(this->h_);
				h_ = nullptr;
				ref_flag_ = false;
			}
		}

		inline HZQDB Parent() { return ZQDBGetCategoryParent(this->h_); }
		inline const char* Name() { return ZQDBGetCategoryName(this->h_); }
		inline ZQDB_HANDLE_TYPE Type() { return ZQDBGetCategoryType(this->h_); }

		inline void Clear() { return ZQDBClearCategory(this->h_); }
		inline HZQDB AppendCategory(const char* name, ZQDB_HANDLE_TYPE type) { return ZQDBAppendCategory(this->h_, name, type); }
		inline size_t AppendSeparator() { return ZQDBAppendCategorySeparator(this->h_); }
		inline size_t AppendValue(HZQDB elem) { return ZQDBAppendCategoryValue(this->h_, elem); }
		inline size_t AppendValue(HZQDB* elem, size_t count) { return ZQDBAppendCategoryValueEx(this->h_, elem, count); }
		inline size_t GetValueCount() { return ZQDBGetCategoryValueCount(this->h_); }
		inline size_t GetValue(HZQDB* elem, size_t count) { return ZQDBGetCategoryValue(this->h_, elem, count); }

	};

	///

	class AllCategory : public std::vector<HZQDB>
	{
		typedef std::vector<HZQDB> Base;

	private:
		HZQDB h_ = nullptr;
		bool ref_flag_ = false;
	public:
		AllCategory() {
			Update();
		}
		AllCategory(HZQDB h, bool ref_flag = false) :h_(h), ref_flag_(ref_flag) {
			if (ref_flag_) {
				ZQDBRefCategory(this->h_);
			}
			Update();
		}
		~AllCategory()
		{
			clear();
			if (this->h_ && ref_flag_) {
				ZQDBCloseCategory(this->h_);
				h_ = nullptr;
				ref_flag_ = false;
			}
		}

		void clear()
		{
			if (Type() == ZQDB_HANDLE_TYPE_CATEGORY) {
				std::vector<HZQDB>& vec = *this;
				for (auto h : vec)
				{
					if (h) {
						ZQDBCloseCategory(h);
					}
				}
			}
			Base::clear();
		}

		inline const char* Name() {
			if (this->h_)
				return ZQDBGetCategoryName(this->h_);
			return "";
		}
		inline ZQDB_HANDLE_TYPE Type() {
			if (this->h_)
				return ZQDBGetCategoryType(this->h_);
			return ZQDB_HANDLE_TYPE_CATEGORY;
		}

		void Update()
		{
			clear();
			std::vector<HZQDB>& vec = *this;
			if (this->h_) {
				auto count = ZQDBGetCategoryValueCount(this->h_);
				if (count > 0) {
					vec.resize(count);
					vec.resize(ZQDBGetCategoryValue(this->h_, &vec[0], vec.size()));
				}
			}
			else {
				auto count = ZQDBGetCategoryCount();
				if (count > 0) {
					vec.resize(count);
					vec.resize(ZQDBGetCategory(&vec[0], vec.size()));
				}
			}
		}
	};

	class AllExchange : public AllTableData {
	public:
		AllExchange(HZQDB h = nullptr) :AllTableData(STR_ZQDB_TABLE_EXCHANGE) {
			std::vector<HZQDB>& vec = *this;
			if (h) {
				switch (h->type)
				{
				case ZQDB_HANDLE_TYPE_MODULE: {
					for (auto it = vec.begin(); it != vec.end(); )
					{
						if (ZQDBGetModule(*it) != h) {
							it = vec.erase(it);
						}
						else {
							++it;
						}
					}
				} break;
				default:
					break;
				}
			}
		}
	};
	class AllProduct : public std::vector<HZQDB> {
	public:
		AllProduct(HZQDB h = nullptr) {
			std::vector<HZQDB>& vec = *this;
			if (!h) {
				AllExchange allexchange;
				for (auto exchange : allexchange)
				{
					auto htb = ZQDBGetTable(exchange);
					auto add_count = ZQDBGetTableDataCount(htb);
					if (add_count) {
						auto old_vec_count = vec.size();
						vec.resize(old_vec_count + add_count);
						vec.resize(old_vec_count + ZQDBGetTableData(htb, 0, &vec[old_vec_count], add_count));
					}
				}
			}
			else {
				switch (h->type)
				{
				case ZQDB_HANDLE_TYPE_EXCHANGE: {
					auto htb = ZQDBGetTable(h);
					auto vec_count = ZQDBGetTableDataCount(htb);
					if (vec_count) {
						vec.resize(vec_count);
						vec.resize(ZQDBGetTableData(htb, 0, &vec[0], vec_count));
					}
				} break;
				case ZQDB_HANDLE_TYPE_MODULE: {
					AllExchange allexchange;
					for (auto exchange : allexchange)
					{
						if (ZQDBGetModule(exchange) != h) {
							continue;
						}
						auto htb = ZQDBGetTable(exchange);
						auto add_count = ZQDBGetTableDataCount(htb);
						if (add_count) {
							auto old_vec_count = vec.size();
							vec.resize(old_vec_count + add_count);
							vec.resize(old_vec_count + ZQDBGetTableData(htb, 0, &vec[old_vec_count], add_count));
						}
					}
				} break;
				default:
					break;
				}
			}
		}
	};
	class AllCode : public std::vector<HZQDB> {
	public:
		AllCode(HZQDB h = nullptr) {
			std::vector<HZQDB>& vec = *this;
			if (h) {
				switch (h->type)
				{
				case ZQDB_HANDLE_TYPE_EXCHANGE: {
					AllProduct products(h);
					for (auto product : products)
					{
						auto htb = ZQDBGetTable(product);
						auto add_count = ZQDBGetTableDataCount(htb);
						if (add_count) {
							auto old_vec_count = vec.size();
							vec.resize(old_vec_count + add_count);
							vec.resize(old_vec_count + ZQDBGetTableData(htb, 0, &vec[old_vec_count], add_count));
						}
					}
				} break;
				case ZQDB_HANDLE_TYPE_PRODUCT: {
					auto htb = ZQDBGetTable(h);
					auto vec_count = ZQDBGetTableDataCount(htb);
					if (vec_count) {
						vec.resize(vec_count);
						vec.resize(ZQDBGetTableData(htb, 0, &vec[0], vec_count));
					}
				} break;
				case ZQDB_HANDLE_TYPE_CODE: {
					vec.emplace_back(h);
				} break;
				case ZQDB_HANDLE_TYPE_CATEGORY: {
					switch (ZQDBGetCategoryType(h))
					{
					case ZQDB_HANDLE_TYPE_EXCHANGE:
					case ZQDB_HANDLE_TYPE_PRODUCT: {
						AllCategory allcat(h);
						for (auto hone : allcat)
						{
							AllCode allcode(hone);
							if (!allcode.empty()) {
								vec.insert(vec.end(), allcode.begin(), allcode.end());
							}
						}
					} break;
					case ZQDB_HANDLE_TYPE_CODE: {
						auto count = ZQDBGetCategoryValueCount(h);
						if (count > 0) {
							vec.resize(count);
							vec.resize(ZQDBGetCategoryValue(h, &vec[0], count));
						}
					} break;
					case ZQDB_HANDLE_TYPE_CATEGORY: {
						AllCategory allcat(h);
						for (auto hone : allcat)
						{
							AllCode allcode(hone);
							if (!allcode.empty()) {
								vec.insert(vec.end(), allcode.begin(), allcode.end());
							}
						}
					} break;
					default: {
					} break;
					}
				} break;
				case ZQDB_HANDLE_TYPE_MODULE: {
					AllExchange allexchange;
					for (auto hexchange : allexchange)
					{
						if (ZQDBGetModule(hexchange) != h) {
							continue;
						}
						AllProduct products(hexchange);
						for (auto hproduct : products)
						{
							auto htb = ZQDBGetTable(hproduct);
							auto add_count = ZQDBGetTableDataCount(htb);
							if (add_count) {
								auto old_vec_count = vec.size();
								vec.resize(old_vec_count + add_count);
								vec.resize(old_vec_count + ZQDBGetTableData(htb, 0, &vec[old_vec_count], add_count));
							}
						}
					}
				} break;
				default:
					break;
				}
			}
			else {
				AllExchange allexchange;
				for (auto hexchange : allexchange)
				{
					AllProduct products(hexchange);
					for (auto hproduct : products)
					{
						auto htb = ZQDBGetTable(hproduct);
						auto add_count = ZQDBGetTableDataCount(htb);
						if (add_count) {
							auto old_vec_count = vec.size();
							vec.resize(old_vec_count + add_count);
							vec.resize(old_vec_count + ZQDBGetTableData(htb, 0, &vec[old_vec_count], add_count));
						}
					}
				}
			}
		}
	};

	class AllModuleUser : public AllTableData {
	public:
		AllModuleUser(HZQDB module) :AllTableData(STR_ZQDB_TABLE_USER, module) {

		}
	};

	class AllModuleAccount : public AllTableData {
	public:
		AllModuleAccount(HZQDB module) :AllTableData(STR_ZQDB_TABLE_ACCOUNT, module) {

		}
	};

	class AllUserAccount : public AllTableDataFilter {
	public:
		AllUserAccount(HZQDB user, HZQDB module) :AllTableDataFilter(user, [](HZQDB h, void* data)->bool {
			if (data) {
				ObjectT<tagAccountInfo> info(h);
				ObjectT<tagUserInfo> user((HZQDB)data);
				return strcmp(info->User, user->User) == 0;
			}
			return true;
		}, STR_ZQDB_TABLE_ACCOUNT, module) {
			//
		}
	};

	class AllModuleInvestor : public AllTableData {
	public:
		AllModuleInvestor(HZQDB module) :AllTableData(STR_ZQDB_TABLE_INVESTOR, module) {

		}
	};

	class AllUserInvestor : public AllTableDataFilter {
	public:
		AllUserInvestor(HZQDB user, HZQDB module) :AllTableDataFilter(user, [](HZQDB h, void* data)->bool {
			if (data) {
				ObjectT<tagInvestorInfo> info(h);
				ObjectT<tagUserInfo> user((HZQDB)data);
				return strcmp(info->User, user->User) == 0;
			}
			return true;
		}, STR_ZQDB_TABLE_INVESTOR, module) {
			//
		}
	};

	class AllModuleOrder : public AllTableData {
	public:
		AllModuleOrder(HZQDB module) :AllTableData(STR_ZQDB_TABLE_ORDER, module) {

		}
	};

	class AllUserOrder : public AllTableDataFilter {
	public:
		AllUserOrder(HZQDB user, HZQDB module = nullptr) :AllTableDataFilter(user, [](HZQDB h, void* data)->bool {
			if (data) {
				ObjectT<tagOrderInfo> info(h);
				ObjectT<tagUserInfo> user((HZQDB)data);
				return strcmp(info->User, user->User) == 0;
			}
			return true;
		}, STR_ZQDB_TABLE_ORDER, module ? module : ZQDBGetModule(user)) {
			//
		}
	};

	class AllModuleTrade : public AllTableData {
	public:
		AllModuleTrade(HZQDB module) :AllTableData(STR_ZQDB_TABLE_TRADE, module) {

		}
	};

	class AllUserTrade : public AllTableDataFilter {
	public:
		AllUserTrade(HZQDB user, HZQDB module = nullptr) :AllTableDataFilter(user, [](HZQDB h, void* data)->bool {
			if (data) {
				ObjectT<tagTradeInfo> info(h);
				ObjectT<tagUserInfo> user((HZQDB)data);
				return strcmp(info->User, user->User) == 0;
			}
			return true;
		}, STR_ZQDB_TABLE_TRADE, module ? module : ZQDBGetModule(user)) {
			//
		}
	};

	class AllModulePosition : public AllTableData {
	public:
		AllModulePosition(HZQDB module) :AllTableData(STR_ZQDB_TABLE_POSITION, module) {

		}
	};

	class AllUserPosition : public AllTableDataFilter {
	public:
		AllUserPosition(HZQDB user, HZQDB module = nullptr) :AllTableDataFilter(user, [](HZQDB h, void* data)->bool {
			if (data) {
				ObjectT<tagPositionInfo> info(h);
				ObjectT<tagUserInfo> user((HZQDB)data);
				return strcmp(info->User, user->User) == 0;
			}
			return true;
		}, STR_ZQDB_TABLE_POSITION, module ? module : ZQDBGetModule(user)) {
			//
		}
	};
}

#endif//

#endif//_H_ZQDB_H_
